package fristphase.day9_23.submarine;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class World extends JPanel{
    public final static int WIDTH = 640,HEIGHT = 480,GAME_OVER = 0,RUNNING = 1,PAUSE = 2;
    public int state = RUNNING;

    private BattleShip battleShip = new BattleShip();
    private SeaObject[] submarines = {};
    private Mine[] mines = {};
    private Bomb[] bombs = {};

    private SeaObject generatorSubmarine(){
        Random random = new Random();
        int type = random.nextInt(20);
        if(type < 10){
            return new ObserveSubmarine();
        }else if(type < 15){
            return new MineSubmarine();
        }else {
            return new TorpedoSubmarine();
        }
    }

    int submarineIndex = 0;
    private void submarineEnterAction(){
        submarineIndex++;
        if(submarineIndex%40 == 0){
            submarines = Arrays.copyOf(submarines,submarines.length+1);
            submarines[submarines.length-1] = generatorSubmarine();
        }
    }

    int mineIndex = 0;
    private void mineEnterAction(){
        mineIndex++;
        for (int i = 0; i < submarines.length; i++) {
            SeaObject sb = submarines[i];

            if(sb instanceof MineSubmarine && sb.getLive()){

                if(mineIndex%40 == 0){
                    MineSubmarine obj = (MineSubmarine) sb;
                    mines = Arrays.copyOf(mines,mines.length+1);
                    mines[mines.length-1] = obj.shootMine();
                }
            }
        }
    }

    private void move(){
        for (int i = 0; i < submarines.length; i++) {
            SeaObject sb = submarines[i];

            if(sb.getLive())sb.move();

        }
        for (int i = 0; i < mines.length; i++) {
            Mine m = mines[i];

            if(m.getLive())m.move();

        }
        for (int i = 0; i < bombs.length; i++) {
            Bomb b = bombs[i];

            if(b.getLive())b.move();

        }
    }

    public void isBoundAction(){
        for (int i = 0; i < submarines.length; i++) {
            SeaObject sb = submarines[i];
            if(sb.isBound() || sb.getDead()){
                submarines[i] = submarines[submarines.length-1];
                submarines = Arrays.copyOf(submarines,submarines.length-1);
            };
        }
        for (int i = 0; i < mines.length; i++) {
            Mine m = mines[i];
            if(m.isBound() || m.getDead()){
                mines[i] = mines[mines.length-1];
                mines = Arrays.copyOf(mines,mines.length-1);
            };
        }
        for (int i = 0; i < bombs.length; i++) {
            Bomb b = bombs[i];
            if(b.isBound() || b.getDead()){
                bombs[i] = bombs[bombs.length-1];
                bombs = Arrays.copyOf(bombs,bombs.length-1);
            };
        }
    }

    int score = 0;
    public void isBombBand(){
        for (int i = 0; i < bombs.length; i++) {
            Bomb b = bombs[i];
            for (int j = 0; j < submarines.length; j++) {
                SeaObject sb = submarines[j];
                if(b.isHit(sb) && b.getLive() && sb.getLive()){
                    b.isDead();
                    sb.isDead();
                    if(sb instanceof ScoreEnemy){
                        ScoreEnemy obj = (ScoreEnemy) sb;
                        score += obj.getScore();
                    }else if(sb instanceof LifeEnemy){
                        LifeEnemy obj = (LifeEnemy) sb;
                        battleShip.addLife(obj.getLife());
                    }
                }
            }
        }
    }

    public void isMineBand(){
        for (int i = 0; i < mines.length; i++) {
            Mine m = mines[i];
            if(m.getLive() && battleShip.getLive() && m.isHit(battleShip)){
                m.isDead();
                battleShip.subtractLife();
            }
        }
    }

    public void isGameOver(){
        if(battleShip.getLife() <= 0)state = GAME_OVER;
    }

    public void paint(Graphics g){

        Images.sea.paintIcon(null,g,0,0);
        g.drawString("SCORE:"+score,150,50);
        g.drawString("LIFE:"+battleShip.getLife(),350,50);
        battleShip.paintImage(g);
        for (int i = 0; i < submarines.length; i++) {
            submarines[i].paintImage(g);
        }
        for (int i = 0; i < mines.length; i++) {
            mines[i].paintImage(g);
        }
        for (int i = 0; i < bombs.length; i++) {
            bombs[i].paintImage(g);
        }
        if(state == GAME_OVER)Images.gameover.paintIcon(null,g,0,0);

    }

    int interval = 10;
    public void action(){
        KeyAdapter k = new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                if(state == RUNNING){
                    if(e.getKeyCode() == KeyEvent.VK_SPACE) {
                        bombs = Arrays.copyOf(bombs,bombs.length+1);
                        bombs[bombs.length-1] = battleShip.shootBomb();
                    }
                    if(e.getKeyCode() == KeyEvent.VK_LEFT)battleShip.moveLeft();
                    if(e.getKeyCode() == KeyEvent.VK_RIGHT)battleShip.moveRight();
                }

                if(e.getKeyCode() == KeyEvent.VK_P){
                    switch (state){
                        case PAUSE:
                            state = RUNNING;
                            break;
                        case RUNNING:
                            state = PAUSE;
                            break;
                        default:
                            break;
                    }

                }

            }
        };
        this.addKeyListener(k);


        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            public void run() {
                if(state == RUNNING){
                    submarineEnterAction();
                    mineEnterAction();
                    move();
                    isBoundAction();
                    isBombBand();
                    isMineBand();
                    isGameOver();
                    repaint();
                }

            }
        },interval,interval);

    }


    public static void main(String[] args) {
        JFrame frame = new JFrame();
        World world = new World();
        world.setFocusable(true);
        frame.add(world);


        frame.setSize(WIDTH,HEIGHT);
        frame.setVisible(true);
        frame.setResizable(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);

        world.action();

    }

}
